package com.cardone.common.annotation.support;

import com.cardone.common.annotation.RunAction;
import com.cardone.common.util.StringUtils;
import com.cardone.context.ContextHolder;
import com.cardone.context.action.Run3Action;
import com.cardone.context.function.Execution2Function;
import com.cardone.context.function.Execution3Function;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.MapUtils;

import java.util.Map;

/**
 * Created by Administrator on 2015/3/23.
 */
public abstract class ErrorRunActionSupport implements Run3Action<RunAction, Object[], Exception> {
    @Setter
    @Getter
    private Execution3Function<String, String, String, String> readDictionaryValueFunction;

    protected Map<String, Object> newParameterMap(RunAction runAction) {
        String message = this.getReadDictionaryValueFunction().execution(runAction.errorMessage(), runAction.errorTypeCode(), runAction.errorCode());

        Map<String, Object> parameterMap = Maps.newHashMap();

        parameterMap.put("message", message);

        return parameterMap;
    }

    protected Map<String, Object> getInputParameterMap(String inputParameterBeanId, Map<String, Object> parameterMap, Object[] args) {
        Object inputParameterBeanObject = ContextHolder.getBean(inputParameterBeanId);

        if (inputParameterBeanObject == null) {
            return parameterMap;
        }

        if (!(inputParameterBeanObject instanceof Execution2Function)) {
            return parameterMap;
        }

        Execution2Function<Map<String, Object>, Map<String, Object>, Object[]> inputParameterBean = (Execution2Function<Map<String, Object>, Map<String, Object>, Object[]>) inputParameterBeanObject;

        return inputParameterBean.execution(parameterMap, args);
    }

    protected Map<String, Object> getParameterMap(RunAction runAction, Object[] args, Exception e) {
        Map<String, Object> parameterMap = this.newParameterMap(runAction);

        String message = MapUtils.getString(parameterMap, "message");

        if (StringUtils.isBlank(message)) {
            message = e.getMessage();
        } else {
            message += ":" + e.getMessage();
        }

        parameterMap.put("message", message);

        return this.getInputParameterMap(runAction.inputParameterBeanId(), parameterMap, args);
    }

    @Override
    public void run(RunAction runAction, Object[] args, Exception e) {
        Map<String, Object> parameterMap = this.getParameterMap(runAction, args, e);

        this.run(runAction, parameterMap);
    }

    protected abstract void run(RunAction runAction, Map<String, Object> parameterMap);
}